#define  GLOBAL_CLK
#include "base.h"
#include "2440lib.h"
#include "option.h"

#include <rt_misc.h>
#include <string.h>

#include "cmd_usb.h"	
#include "cmd_fat.h"

#include "gm_usb.h"

extern void s_TimerInit(void);

unsigned char usb_wr_buf[50];

static void cal_cpu_bus_clk(void);


void DelayMs(unsigned short ms)
{
    int i,j;
    for(i=0;i<ms;i++)
    for(j=0;j<51000;j++);//75000=1.4ms 50000=986us
}


static U32 cpu_freq;
static U32 UPLL;



static void cal_cpu_bus_clk(void)
{
	U32 val;
	U8 m, p, s;
	
	val = rMPLLCON;
	m = (val>>12)&0xff;
	p = (val>>4)&0x3f;
	s = val&3;
	
	FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;
	
	val = rCLKDIVN;
	m = (val>>1)&3;
	p = val&1;	
	val = rCAMDIVN;
	s = val>>8;
	
	switch (m) {
	case 0:
		HCLK = FCLK;
		break;
	case 1:
		HCLK = FCLK>>1;
		break;
	case 2:
		if(s&2)
			HCLK = FCLK>>3;
		else
			HCLK = FCLK>>2;
		break;
	case 3:
		if(s&1)
			HCLK = FCLK/6;
		else
			HCLK = FCLK/3;
		break;
	}
	
	if(p)
		PCLK = HCLK>>1;
	else
		PCLK = HCLK;
	
	if(s&0x10)
		cpu_freq = HCLK;
	else
		cpu_freq = FCLK;
		
	val = rUPLLCON;
	m = (val>>12)&0xff;
	p = (val>>4)&0x3f;
	s = val&3;
	UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
	if(UPLL==96*MEGA)
		rCLKDIVN |= 8;	//UCLK=UPLL/2
	UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;

}


void u2440mon_main(void)
{
   	
	U8 key;
	U32 mpll_val;
    
	
	#if ADS10   
	 __rt_lib_init(0,0); //for ADS 1.0
	#endif

	Port_Init();
	rGPACON &= ~(1<<11);
	rGPADAT |= 1<<11;	

	switch (2) {
	case 0:	//240
		key = 14;
		mpll_val = (112<<12)|(4<<4)|(1);
		break;
	case 1:	//320
		key = 14;
		mpll_val = (72<<12)|(1<<4)|(1);
		break;
	case 2:	//400
		key = 14;
		mpll_val = (92<<12)|(1<<4)|(1);
		break;
	case 3:	//440!!!
		key = 14;
		mpll_val = (102<<12)|(1<<4)|(1);
		break;
	default:
		key = 14;
		mpll_val = (92<<12)|(1<<4)|(1);
		break;
	}
	
#if 1
	//init FCLK=400M, so change MPLL first
	ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
	ChangeClockDivider(key, 12);
	cal_cpu_bus_clk();
	if(PCLK<(40*MEGA)) {
		ChangeClockDivider(key, 11);
		cal_cpu_bus_clk();
	}
#else
	cal_cpu_bus_clk();
#endif
	
	Uart_Init(0,112500);	
}



int Main(void)
{
    char cmd;
    char *tempbuf[100];
    char temppath[1000];
    unsigned char buffer[10000];
    int i,ret;  
    
	s_UartPrint("in %s, %d.\n",__func__, __LINE__);
	
	u2440mon_main();
	
    /* 将端口B组部分引脚设置为输出. */
	rGPBCON=rGPBCON&(~0x3ff00)|(0x15500);
    /* GPB5-gpio low level */
	rGPBDAT&=~(1<<5);
    /* GPB8-gpio low level */
	rGPBDAT&=~(1<<8);
    /* GPB6-gpio high level */
	rGPBDAT|=(1<<6);
    /* GPB7-gpio high level */
	rGPBDAT|=(1<<7);
	
    memset(tempbuf,0,sizeof(tempbuf));	
	
    s_TimerInit();
    
#if 0
    for(i=0;i<sizeof(usb_wr_buf);i++)
      usb_wr_buf[i]=0x70+i;
#endif

	//s_usbhost_reset();
    while(1)
    {
        s_UartPrint("-------------------------\n");
	    s_UartPrint("1-Start  2-Stop   3-Tree \n");
	    s_UartPrint("4-Scan   5-Stor   6-Part \n");
	    s_UartPrint("7-Info   8-Read   9-Dev  \n");
	    s_UartPrint("---------w-Write---------\n");
	    s_UartPrint("l-List   i-fsinfo r-read \n");
	    s_UartPrint("-------------------------\n");
				
		s_UartPrint("\nPlease Select Function Key:\n");
        cmd=s_getkey();
        s_UartPrint("\n");
        
        switch(cmd)
        {
	        case '1':
	            s_UartPrint("s_usbhost_start() \n");
	            s_usbhost_start();
	            break;
	        case '2':
	            s_UartPrint("s_usbhost_stop() \n");
	            s_usbhost_stop();
	            s_UartPrint("s_usbhost_dev(2, tempbuf) \n");
	          //  s_usbhost_read(2,8,buffer);
	            break;
	        case '3':
	            s_UartPrint("s_usbhost_tree() \n");
	            s_usbhost_tree();
	            break;
	        case '4':
	            s_UartPrint("s_usbhost_scan() \n");
	            s_usbhost_scan();
	            break;
	        case '5':
	            s_UartPrint("s_usbhost_stor() \n");
	          //  s_usbhost_stor();
	            break;
	        case '6':
	            s_UartPrint("s_usbhost_part() \n");
	            s_usbhost_part();
	            break;
	        case '7':
	            s_UartPrint("s_usbhost_info(2, tempbuf) \n");
	            s_usbhost_info(2, tempbuf);
	            break;
	            
	        case '8':
	            s_UartPrint("s_usbhost_read(5, tempbuf) \n");
	            s_usbhost_dev(0);
	            s_usbhost_read(0,1,buffer);            
	            s_usbhost_read(9,50,buffer);
	           
	            break;
	        case '9':
	            s_UartPrint("s_usbhost_dev(0, tempbuf) \n");
	            s_usbhost_dev(0);
	            break;
	        case '0':
	            s_UartPrint("s_usbhost_dev(1, tempbuf) \n");
	            s_usbhost_read(1,8,buffer);
	            break;
	            
	        case 'w':
	        case 'W':
	            s_UartPrint("s_usbhost_write!\n");
	            s_usbhost_dev(0);
	       //     s_usbhost_write(9,1,usb_wr_buf);           
	            break;
	            
	        case 'l':
	        case 'L':
	            s_UartPrint("do_fat_ls () \n");
	            memset(temppath,0,sizeof(temppath));
	            strcpy(temppath,"\\");
	            do_fat_ls (temppath);
	            break;
	            
	        case 'i':
	        case 'I':
	            s_UartPrint("do_fat_fsinfo() \n");
	            do_fat_fsinfo ();
	            break;
	            
	        case 'r':
	        case 'R':			
	            s_UartPrint("do_fat_fsload(0,5) \n");
	            ret=do_fat_fsload ("readme.txt",buffer,0,5);			
	            s_UartPrint("ret=%d \n",ret);
	            s_UartPrint("do_fat_fsload(5,15) \n");
	            ret=do_fat_fsload ("readme.txt",buffer,5,15);
	            s_UartPrint("ret=%d  \n",ret);
	            
	            break;
        }
    }
    return 0;
}
